use actix_web::{web, HttpResponse, Result};
use async_graphql::http::{playground_source, GraphQLPlaygroundConfig};
use async_graphql::{EmptySubscription, Schema};
use async_graphql_actix_web::{Request, Response};

use crate::dbs::sqlite::{peer, rbatis_pool};
use crate::features::gnode::Node;
use crate::gql::{mutations::MutationRoot, queries::QueryRoot};
//use crate::util::constant::CFG;

pub type ActixSchema = Schema<QueryRoot, MutationRoot, async_graphql::EmptySubscription>;

pub async fn build_schema(data_dir:&str,sqlite_file_path:&str) -> ActixSchema {
  // 获取 mysql 数据池后，可以将其增加到：
  // 1. 作为 async-graphql 的全局数据；
  // 2. 作为 actix-web 的应用程序数据，优势是可以进行原子操作；
  // 3. 使用 lazy-static.rs
  let rbatis_pool = rbatis_pool(sqlite_file_path).await;
  let local_peer = peer(data_dir).await;

  // The root object for the query and Mutatio, and use EmptySubscription.
  // Add global mysql pool  in the schema object.
  Schema::build(QueryRoot, MutationRoot, EmptySubscription)
    .register_type::<Node>()
    .data(rbatis_pool)
    .data(local_peer)
    .finish()
}

pub async fn graphql(schema: web::Data<ActixSchema>, req: Request) -> Response {
  schema.execute(req.into_inner()).await.into()
}

pub async fn graphiql() -> Result<HttpResponse> {
  Ok(
    HttpResponse::Ok()
      .content_type("text/html; charset=utf-8")
      .body(playground_source(
        GraphQLPlaygroundConfig::new("v1" /*CFG.get("GQL_VER").unwrap()*/)
          .subscription_endpoint("v1i" /*CFG.get("GQL_VER").unwrap()*/),
      )),
  )
}
